home *** CD-ROM | disk | FTP | other *** search
- Path: news.compuserve.com!newsmaster
- From: Philippe Verdy <100105.3120@compuserve.com>
- Newsgroups: comp.lang.c++
- Subject: Re: casting a void pointer back to a function pointer
- Date: 5 Apr 1996 21:34:19 GMT
- Organization: CompuServe Incorporated
- Message-ID: <4k43kr$2ap@dub-news-svc-3.compuserve.com>
- NNTP-Posting-Host: hd41-018.compuserve.com
-
- What you want to do is not portable, because code pointers
- and data pointers may be stored differently (mainly on DOS
- platforms, in compact and medium memory models). In order
- to safely typecast a function pointer to a data pointer, you'll
- need additional pointer model specifiers.
- However, assuming the memory model you are using is not
- concerned (using small, large, huge, and the common flat
- memory models), you can do the following :
-
- dlabell@pcs.cnu.edu (Daniel LaBell) wrote :
- > I'm going to skip explaining why I want to do this, and get right to the
- > problem. How do I cast a pointer to a function pointer?
- >
- > Here is trivial example that shows the problem.
- >
- > void foo1(){ cout << " foo1 " << endl; }
- > void foo2(){ cout << " foo2 " << endl; }
- > void foo3( int x )
- > { cout << " foo3, argument = " << x << endl; }
- >
- > void do_a_foo( void (*fun)() )
- > { (*fun)(); }
- > void do_a_foo2( int x, void (*fun) (int ) )
- > { (*fun) ( x ); }
- > int main()
- > {
- > do_a_foo ( foo1 );
- > do_a_foo ( foo2 );
- > do_a_foo2 ( 2, foo3 );
-
- Here is the danger (warnings: segment lost in conversion, etc...)
- > void * x=foo2;
- You should declare a large enough data pointer type under DOS
- using the _far keyword, embedded in a FAR macro used for porting
- reasons (if you need to compile for DOS):
- #ifndef FAR
- # if defined(MSDOS) || defined(WINDOWS) && !defined(WIN32)
- # define FAR _far
- # else
- # define FAR //nothing
- # endif
- #endif
- ...
- void FAR* x = (void FAR*)foo2;
-
- The solution to your problem :
- > do_a_foo (x); // I don't know the syntax to do this cast. :(
- is then:
- do_a_foo( (void (*)()) x );
- which uses a function pointer typecast. Here the typecast means
- it is a pointer to a function taking no parameter, and returning
- void... Such typecast is really dangerous, because using it on
- undetermined pointers will may be completely hang the system
- or corrupt your current process under Unix. No type-checking
- also occurs on parameters and on the returned type, so the
- called function may fail within its execution, or the calling
- function may hang at return time !!!
-
- You'll only need it when you have to pass a generic client
- pointer (of type void*) as an argument to an API function
- which enables you to return to your code thru a specified
- callback.
-
- But I would advise you to prefereably create a structure
- containing the function pointer, declared like this :
- struct parameter {
- void (*pf)();
- };
- then safely assign parameter::pf with x;
- finally call your API using a reference or pointer to your
- parameter structure.
- When you get this pointer (say parameter *p), you can call
- back the assigned function like this:
- (*p->pf) ();
- or simply:
- p->pf ();
- Hope this will help...
-
- > return 0;
- > }
- > I get this warning message from g++:
- > :/home/student/dlabell/C/test.cc: In function `int main()':
- > :/home/student/dlabell/C/test.cc:21: warning: ANSI C++ forbids implicit conversion from `void *' in argument passing
- > :
- > :Compilation finished at Thu Apr 4 01:18:20
- >
- > So, now my program isn't portable, and if I overload do_a_foo instead of
- > making do_a_foo2, it wouldn't compile at all. So, I need to know the syntax
- > for casting a pointer to a pointer to a function. Can this be done in a
- > portable way? ( how about for ANSI C? ) If not, can this be done in
- > g++/gcc? And also if it isnt ANSI wouldn't that violate the premise that
- > "any pointer can be cast to void * and back again without loss of
- > information"? Or can I declare a type of pointer to a function?
- >
- >
- > --
- > Daniel LaBell
-
-